#include<iostream>
#include<pthread.h>
#include<vector>
#include <semaphore.h>
using namespace std;

#define DEFAULT_CAP 10

template<class T>
class RingQueue
{
public:
  RingQueue()
    :_cap(DEFAULT_CAP),c_pos(0),p_pos(0)
  {
    _ringQueue.resize(_cap);
    sem_init(&data_sem,0,0);
    sem_init(&blank_sem,0,_cap);
  }
  ~RingQueue()
  {
    sem_destroy(&data_sem);
    sem_destroy(&blank_sem);
  }
 void push(const T& val)
 {
    sem_wait(&blank_sem); 
    _ringQueue[p_pos++] = val;
    sem_post(&data_sem);
    p_pos %= _cap;
 }
 void pop(T* out)
 {
    sem_wait(&data_sem);
    *out = _ringQueue[c_pos++];
    sem_post(&blank_sem);
    c_pos %= _cap;
 }

private:
  int _cap;
  std::vector<T> _ringQueue; 
  int c_pos;
  int p_pos;
  sem_t data_sem; 
  sem_t blank_sem;
};
